home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / doorm003 / doormail.c next >
C/C++ Source or Header  |  1994-04-07  |  21KB  |  804 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stddef.h>
  4. #include <string.h>
  5. #include <fido.h>
  6. #include <ext.h>
  7. #include <tos.h>
  8. #include <ctype.h>
  9. #include <time.h>
  10.  
  11. #define MAX_STR            256
  12. #define TRUE                1
  13. #define FALSE                0
  14. #define    EOS                    '\0'
  15. #define MIN(x,y)        ((x)<(y)) ? (x) : (y)
  16. #define MAX(x,y)        ((x)>(y)) ? (x) : (y)
  17. #define MINSTACK        100
  18. #define    MAXSTACK        10000
  19. #define MAXALLOWED    100
  20.  
  21. #define X_FIXNAME        "Doormail"
  22. #define X_TEARLINE    "\n=== Doormail V0.03\n"
  23. #define X_PID                "\001PID: Doormail 0.03\n"
  24.  
  25. #define C_EXEC        (1 << 0)
  26. #define    C_DEL            (1 << 1)
  27. #define C_REQUEST    (1 << 2)
  28. #define    C_NOTIFY    (1 << 3)
  29.  
  30. extern int match(char *pattern,char *string);
  31. extern int matchfile(char *pattern,char *filename);
  32.  
  33. void convert(char *buffer, int *length);
  34. char *mergeaddr(char *addr,int zone,int net,int node,int point,char *domain);
  35. void scanaddr(char *addr,int *zone,int *net,int *node,int *point,char *domain);
  36. void trim(char **dest);
  37. void parse(char *buffer,int size);
  38. void parse_it(char *line);
  39. void writenotify(void);
  40. void delete_unused_flags(MSG_HEADER *header);
  41. void input(char *string, int max, FILE *ftype);
  42. int  do_exec(char *fname);
  43. char *trimstr(char *str);
  44. void getpfad(char *fname, char *xpfad);
  45. void log_it(char *text);
  46. int  xFsfirst(const char *filename,int attr);
  47. int     xFsnext(void);
  48. int  delete(char *fname);
  49. int  teste_ob_in_okfile(char *filename);
  50. int  untersuche_ordner(char *fname,char *request,int add);
  51. char *addr2file36(unsigned int net,unsigned int node,unsigned int point);
  52. void add_slash(char *path);
  53.  
  54.  
  55. typedef struct { char    name[40],
  56.                                             passwd[40];
  57.                                             int        zone,net,node,point,
  58.                                                         wildcards,
  59.                                                         nopasswd,
  60.                                                         cmd;
  61.                              } ALLOWED;
  62. typedef struct { char line[128];
  63.                              } ERRSTACK;
  64.  
  65. char    netmail[PATH_MAX]="",
  66.             logfile[PATH_MAX]="",
  67.             okfile[PATH_MAX]="",
  68.             outbound[PATH_MAX]="",
  69.             buffer[65535U],*fbuffer;
  70. int        myzone,mynet,mynode,mypoint,
  71.             allowed_cnt=0,
  72.             err_cnt,
  73.             max_errline,
  74.             wildcard=FALSE,
  75.             aktive_user;
  76.  
  77. ERRSTACK        *errstack;
  78. ALLOWED            allowed[MAXALLOWED];
  79. MSG_HEADER     mh;
  80. FILE                *fhdr,*fmsg;
  81. DTA                    dta_buffer;
  82.  
  83. int main(void)
  84.     {    char    temp[MAX_STR],*pointer;
  85.         long    size,msgs,i,t;
  86.         int        noerror,j;
  87.  
  88.         t = (((long)Malloc(-1L))-65536L)/sizeof(*errstack);
  89.         if (t>MAXSTACK)    t=MAXSTACK;
  90.         if (t<MINSTACK)    t=MINSTACK;
  91.         max_errline = (int) t;
  92.         errstack = (ERRSTACK *) calloc(max_errline+2,sizeof(*errstack));
  93.  
  94.         fbuffer=(char *)malloc(sizeof(MSG_HEADER)*40);
  95.         if (fbuffer==NULL)
  96.             {    free(errstack);
  97.                 exit(1);
  98.             }
  99.  
  100.         fhdr = fopen("DOORMAIL.CFG","rb");
  101.         do
  102.             {    input(temp,MAX_STR,fhdr);
  103.                 pointer=temp; trim(&pointer); strcpy(temp,pointer);
  104.                 if (strnicmp(temp,"WILDCARD",8)==0)
  105.                     {    wildcard=TRUE;
  106.                         continue;
  107.                     }
  108.                 if (strnicmp(temp,"NETMAIL ",8)==0)
  109.                     {    pointer+=8;    trim(&pointer);
  110.                         strcpy(netmail,pointer);
  111.                         continue;
  112.                     }
  113.                 if (strnicmp(temp,"LOGFILE ",8)==0)
  114.                     {    pointer+=8;    trim(&pointer);
  115.                         strcpy(logfile,pointer);
  116.                         continue;
  117.                     }
  118.                 if (strnicmp(temp,"OKFILE ",7)==0)
  119.                     {    pointer+=7;    trim(&pointer);
  120.                         strcpy(okfile,pointer);
  121.                         continue;
  122.                     }
  123.                 if (strnicmp(temp,"OUTBOUND ",9)==0)
  124.                     {    pointer+=9;    trim(&pointer);
  125.                         strcpy(outbound,pointer);
  126.                         add_slash(outbound);
  127.                         continue;
  128.                     }
  129.                 if (strnicmp(temp,"ADDRESS ",8)==0)
  130.                     {    pointer+=8;    trim(&pointer);
  131.                         scanaddr(pointer,&myzone,&mynet,&mynode,&mypoint,temp);
  132.                         continue;
  133.                     }
  134.                 if (strnicmp(temp,"PASSWORD ",9)==0)
  135.                     {    pointer+=9;    trim(&pointer); strcpy(temp,pointer);
  136.                         pointer=strtok(temp," ");
  137.                         allowed_cnt++;
  138.                         allowed[allowed_cnt].wildcards=FALSE;
  139.                         allowed[allowed_cnt].nopasswd=TRUE;
  140.                         allowed[allowed_cnt].cmd=-1;    /* Alle erlaubt */
  141.                         while (*pointer=='#' || *pointer=='!')
  142.                             {    if (*pointer=='!')
  143.                                     {    strcpy(allowed[allowed_cnt].passwd,pointer+1);
  144.                                         allowed[allowed_cnt].nopasswd=FALSE;
  145.                                     }
  146.                                 if (*pointer=='#')
  147.                                     {    allowed[allowed_cnt].cmd=0;
  148.                                         if (strchr(pointer+1,'*')!=NULL)
  149.                                             allowed[allowed_cnt].wildcards=TRUE;
  150.                                         if (strchr(pointer+1,'e')!=NULL ||
  151.                                                 strchr(pointer+1,'E')!=NULL )
  152.                                             allowed[allowed_cnt].cmd |= C_EXEC;
  153.                                         if (strchr(pointer+1,'n')!=NULL ||
  154.                                                 strchr(pointer+1,'N')!=NULL )
  155.                                             allowed[allowed_cnt].cmd |= C_NOTIFY;
  156.                                         if (strchr(pointer+1,'r')!=NULL ||
  157.                                                 strchr(pointer+1,'R')!=NULL )
  158.                                             allowed[allowed_cnt].cmd |= C_REQUEST;
  159.                                         if (strchr(pointer+1,'d')!=NULL ||
  160.                                                 strchr(pointer+1,'D')!=NULL )
  161.                                             allowed[allowed_cnt].cmd |= C_DEL;
  162.                                     }
  163.                                 pointer=strtok(NULL," ");
  164.                             }
  165.                         scanaddr(pointer,    &allowed[allowed_cnt].zone,
  166.                                                             &allowed[allowed_cnt].net,
  167.                                                             &allowed[allowed_cnt].node,
  168.                                                             &allowed[allowed_cnt].point,temp);
  169.                         pointer=strtok(NULL,"");
  170.                         trim(&pointer);
  171.                         strcpy(allowed[allowed_cnt].name,pointer);
  172.                         continue;
  173.                     }
  174.             }
  175.         while (feof(fhdr)==0);
  176.         fclose(fhdr);
  177.  
  178.         sprintf(temp,"%s.HDR",netmail);
  179.         fhdr = fopen( temp,"r+b" );
  180.         setvbuf(fhdr,fbuffer,_IOFBF,sizeof(MSG_HEADER)*40);
  181.  
  182.         size = filelength( fhdr->Handle);
  183.         msgs = size / sizeof( MSG_HEADER );
  184.  
  185.         for (i=1; i<=msgs; i++)
  186.             {    noerror=0;
  187.                 if (fread( &mh,sizeof(MSG_HEADER),1,fhdr)==1)
  188.                     noerror |= 1;
  189.  
  190.                 if (!mh.wProcessed.Doormail && !(mh.wFlags & MF_DELETED))
  191.                     {
  192.                         if (stricmp(mh.szTo,X_FIXNAME)==0)
  193.                             noerror |= 2;
  194.                         if (mh.wToZone ==myzone  &&    mh.wToNet  ==mynet   &&
  195.                                 mh.wToNode ==mynode  &&    mh.wToPoint==mypoint)
  196.                             noerror |= 4;
  197.  
  198.                         aktive_user=0;
  199.                         for (j=1; j<=allowed_cnt; j++)
  200.                             {    if (stricmp(mh.szFrom,allowed[j].name)==0 &&
  201.                                         (stricmp(mh.szSubject,allowed[j].passwd)==0 || allowed[j].nopasswd==TRUE) &&
  202.                                         mh.wFromZone ==allowed[j].zone  &&
  203.                                         mh.wFromNet  ==allowed[j].net   &&
  204.                                         mh.wFromNode ==allowed[j].node  &&
  205.                                         mh.wFromPoint==allowed[j].point)
  206.                                     {    noerror |= 8;
  207.                                         aktive_user=j;
  208.                                         break;
  209.                                     }
  210.                             }
  211.  
  212.                         if ( noerror==15 )
  213.                             {    sprintf(temp,"Message to Doormail from %s",mh.szFrom);
  214.                                 log_it(temp);
  215.                                 err_cnt=0;
  216.                                 sprintf(temp,"%s.MSG",netmail);
  217.                                 fmsg = fopen( temp,"rb" );
  218.                                 fseek(fmsg,mh.lStart,SEEK_SET);
  219.                                 fread(&buffer,sizeof(char),mh.wSize,fmsg);
  220.                                 fclose(fmsg);
  221.  
  222. #if !defined( TEST )
  223.                                 fflush(fhdr);
  224.                                 fseek(fhdr,-sizeof(MSG_HEADER),SEEK_CUR);
  225.                                 mh.wProcessed.Doormail = TRUE;
  226.                                 fwrite(&mh,sizeof(MSG_HEADER),1,fhdr);
  227.                                 fflush(fhdr);
  228. #endif
  229.  
  230.                                 convert(buffer,&mh.wSize);
  231.                                 buffer[mh.wSize] = EOS;
  232.                                 parse(buffer,mh.wSize);
  233.                             }
  234.                         else
  235.                             {    if ( noerror==15-8 )
  236.                                     {    mergeaddr(buffer,mh.wFromZone,mh.wFromNet,mh.wFromNode,mh.wFromPoint,"");
  237.                                         sprintf(temp,"Warning! Mail to Doormail from %s on %s (%s)",mh.szFrom,buffer,mh.szSubject);
  238.                                         log_it(temp);
  239.                                     }
  240.                             }
  241.                     }
  242.             }
  243.  
  244.         fclose(fhdr);
  245.         free(fbuffer);
  246.         free(errstack);
  247.  
  248.         return 0;
  249.     }
  250.  
  251. void parse(char *buffer,int size)
  252.     {    char *pointer;
  253.         pointer=strtok(buffer,"\n\r");
  254.         while (pointer!=NULL && (pointer<buffer+size))
  255.             {    trim(&pointer);
  256.                 if (strcmp(pointer,"---")==0)
  257.                     return;
  258.                 if (*pointer!=EOS)
  259.                     parse_it(pointer);
  260.                 pointer=strtok(NULL,"\n\r");
  261.             }
  262.     }
  263.  
  264. void parse_it(char *line)
  265.     {    char temp[MAX_STR];
  266.         int i;
  267.  
  268.         strcpy(temp,line);
  269.         strcpy(errstack[++err_cnt].line,temp);
  270.  
  271.         if (strnicmp(temp,"%NOTIFY",7)==0)
  272.             {    if (allowed[aktive_user].cmd & C_NOTIFY)
  273.                     {    writenotify();
  274.                     }
  275.                 else
  276.                     {    strcpy(errstack[++err_cnt].line,"> NOTIFY disabled!");
  277.                         log_it("NOTIFY denied");
  278.                     }
  279.                 return;
  280.             }
  281.  
  282.         if (strnicmp(temp,"%DEL ",5)==0)
  283.             {    if (allowed[aktive_user].cmd & C_DEL)
  284.                     {    if (delete(temp+5)==-32767)
  285.                             strcpy(errstack[++err_cnt].line,"> Error in DEL! Filename was missing!");
  286.                     }
  287.                 else
  288.                     {    strcpy(errstack[++err_cnt].line,"> DEL disabled!");
  289.                         log_it("DEL denied");
  290.                     }
  291.                 return;
  292.             }
  293.  
  294.         if (strnicmp(temp,"%EXEC ",6)==0)
  295.             {    if (allowed[aktive_user].cmd & C_EXEC)
  296.                     {    switch(i=do_exec(temp+6))
  297.                             { case -32767 : strcpy(errstack[++err_cnt].line,"> Error in EXEC! Filename was missing!"); break;
  298.                                 case            0    : break;
  299.                                 default            :    sprintf(errstack[++err_cnt].line,"> EXEC returns %d",i);
  300.                             }
  301.                     }
  302.                 else
  303.                     {    strcpy(errstack[++err_cnt].line,"> EXEC disabled!");
  304.                         log_it("EXEC denied");
  305.                     }
  306.                 return;
  307.             }
  308.  
  309.         if (allowed[aktive_user].cmd & C_REQUEST)
  310.             {    i=teste_ob_in_okfile(temp);
  311.                 log_it(temp);
  312.                 sprintf(temp," ... %u match%s",i,i==1 ? "" : "es");
  313.                 strcat(errstack[err_cnt].line,temp);
  314.                 log_it(temp);
  315.             }
  316.         else
  317.             {    strcpy(errstack[++err_cnt].line,"> REQUEST disabled!");
  318.                 log_it("REQUEST denied");
  319.             }
  320.     }
  321.  
  322.  
  323.  
  324.  
  325.  
  326. int untersuche_ordner(char *fname,char *request,int add)
  327.     {    char source[PATH_MAX],pfad[PATH_MAX],temp[PATH_MAX],*pointer;
  328.         int error,i=0;
  329.         FILE *fp;
  330.  
  331.         strcpy(source,fname);
  332.         getpfad(source,pfad);
  333.         
  334. /*
  335. **    Ist es ein Request MIT Wildcards und ist Request ein 
  336. **    Pattern von fname?
  337. */
  338.         if (strchr(request,'*')==NULL &&
  339.                 strchr(request,'?')==NULL)
  340.             {    pointer=strrchr(fname,'\\');
  341.                 if (pointer!=NULL)
  342.                     pointer++;
  343.                 else
  344.                     pointer=fname;
  345.                 if (matchfile(pointer,request))
  346.                     {    strcpy(source,pfad);
  347.                         strcat(source,request);
  348.                     }
  349.             }
  350.  
  351.         error=xFsfirst(source,0);
  352.         if (error<0)
  353.             {    return 0;
  354.             }
  355.         while (error>=0)
  356.             {    strcpy(source,pfad);
  357.                 strcat(source,dta_buffer.d_fname);
  358.                 
  359.                 if (matchfile(request,dta_buffer.d_fname))
  360.                     {    i++;
  361.                         if (add)
  362.                             {    strcpy(temp,outbound);
  363.                                 strcat(temp,addr2file36(allowed[aktive_user].net,
  364.                                                                                 allowed[aktive_user].node,
  365.                                                                                 allowed[aktive_user].point));
  366.                                 strcat(temp,".HFT");
  367.                                 fp=fopen(temp,"a");
  368.                                 fputs(source,fp); fputc('\n',fp);
  369.                                 fclose(fp);
  370.                             }
  371.                     }
  372.                 error=xFsnext();
  373.             }
  374.         return i;
  375.     }
  376.  
  377. int teste_ob_in_okfile(char *request)
  378.     {    FILE *fp;
  379.         int i;
  380.         char temp[MAX_STR],
  381.                  t1[MAX_STR],
  382.                  t2[MAX_STR],
  383.                  t3[MAX_STR],
  384.                  filepassword[MAX_STR],
  385.                  *pointer,
  386.                  matches=0;
  387.  
  388.         if (wildcard==FALSE && allowed[aktive_user].wildcards==FALSE)
  389.             {    pointer=request;
  390.                 while (*pointer!=EOS && *pointer!='.')
  391.                     {    if (*pointer=='*' || *pointer=='?')
  392.                             {    strcpy(errstack[++err_cnt].line,"> Sorry no wildcards in filenames allowed!");
  393.                                 return 0;
  394.                             }
  395.                         pointer++;
  396.                     }
  397.             }
  398.  
  399.         *filepassword=EOS;
  400.         switch(sscanf(request,"%s %s",&t1,&t2))
  401.             {    case 0    :    return 0;
  402.                 case 1    :    break;
  403.                 case 2    : strcpy(request,t1);
  404.                                     strcpy(filepassword,t2);
  405.                                     break;
  406.             }
  407.  
  408.         if (*okfile)
  409.             {    fp=fopen(okfile,"r");
  410.                 do
  411.                     {    input(temp,MAX_STR,fp);
  412.                         pointer=temp; trim(&pointer); strcpy(temp,pointer);
  413.  
  414.                         switch(sscanf(temp,"%s %s %s",&t1,&t2,&t3))
  415.                             {    case 0    :    
  416.                                 case EOF:    break;
  417.                                 case 1    : {    /* Kein Pažwort */
  418.                                                         matches += untersuche_ordner(t1,request,TRUE);
  419.                                                     }    break;
  420.                                 case 2    : {    if (*t1=='@')
  421.                                                             {    /* MAGIC ohne Pažwort*/
  422.                                                                 if (stricmp(request,t1+1)==0)
  423.                                                                     {    pointer=strrchr(t2,'\\');
  424.                                                                         if (pointer!=NULL)
  425.                                                                             pointer++;
  426.                                                                         else
  427.                                                                             pointer=t2;
  428.                                                                         matches += untersuche_ordner(t2,pointer,TRUE);
  429.                                                                     }
  430.                                                             }
  431.                                                         else
  432.                                                             {    /* Request mit Pažwort */
  433.                                                                 if (stricmp(filepassword,t2+1)==0)
  434.                                                                     {    matches += untersuche_ordner(t1,request,TRUE);
  435.                                                                     }
  436.                                                                 else
  437.                                                                     {    if ((i=untersuche_ordner(t1,request,FALSE))!=0)
  438.                                                                             {    strcpy(errstack[++err_cnt].line,"> Sorry, wrong or missing password!");
  439.                                                                                 log_it(" ... wrong or missing password");
  440.                                                                             }
  441.                                                                         matches+=i;
  442.                                                                     }
  443.                                                             }
  444.                                                     } break;
  445.                                 case 3    : {    /* MAGIC mit Pažwort */
  446.                                                         if (stricmp(request,t1+1)==0)
  447.                                                             {    pointer=strrchr(t3,'\\');
  448.                                                                 if (pointer!=NULL)
  449.                                                                     pointer++;
  450.                                                                 else
  451.                                                                     pointer=t3;
  452.                                                                 if (stricmp(filepassword,t2+1)==0)
  453.                                                                     {    matches += untersuche_ordner(t3,pointer,TRUE);
  454.                                                                     }
  455.                                                                 else
  456.                                                                     {    if ((i=untersuche_ordner(t3,pointer,FALSE))!=0)
  457.                                                                             {    strcpy(errstack[++err_cnt].line,"> Sorry, wrong or missing password!");
  458.                                                                                 log_it(" ... wrong or missing password");
  459.                                                                             }
  460.                                                                         matches+=i;
  461.                                                                     }
  462.                                                             }
  463.                                                     } break;
  464.                                 default    :    log_it("ERROR! ERROR in OKFILE!");
  465.                             }
  466.                     }
  467.                 while (feof(fp)==0);
  468.                 fclose(fp);
  469.             }
  470.         else
  471.             {    strcpy(errstack[++err_cnt].line,"> Request not possible!");
  472.             }
  473.         return matches;
  474.     }
  475.  
  476.  
  477.  
  478. int delete(char *fname)
  479.     {    char source[PATH_MAX],pfad[PATH_MAX],*start;
  480.         signed int error;
  481.  
  482.         log_it("Following files deleted:");
  483.         start=fname; trim(&start); strcpy(fname,start);
  484.         if (*fname==EOS)
  485.             {    log_it("None (filename missing)");
  486.                 return(-32767);
  487.             }
  488.  
  489.         strcpy(source,start);
  490.         getpfad(source,pfad);
  491.         error=xFsfirst(source,0);
  492.         if (error<0)
  493.             {    sprintf(source,"None (%s not found)",source);
  494.                 log_it(source);
  495.                 strcpy(errstack[++err_cnt].line,"> File not found");
  496.             }
  497.         while (error>=0)
  498.             {    strcpy(source,pfad);
  499.                 strcat(source,dta_buffer.d_fname);
  500.                 if (Fdelete(source)!=0)
  501.                     {    sprintf(source,"Unable to kill %s",dta_buffer.d_fname);
  502.                         log_it(source);
  503.                         sprintf(errstack[++err_cnt].line,">%s unable to delete",dta_buffer.d_fname);
  504.                     }
  505.                 else
  506.                     {    log_it(dta_buffer.d_fname);
  507.                         sprintf(errstack[++err_cnt].line,">%s",dta_buffer.d_fname);
  508.                     }
  509.                 error=xFsnext();
  510.             }
  511.         return 0;
  512.     }
  513.  
  514. int do_exec(char *fname)
  515.     {    char source[PATH_MAX],cmd[PATH_MAX],temp[MAX_STR],*start;
  516.         int    drive=0;
  517.         start=fname; trim(&start); strcpy(fname,start);
  518.         if (*fname==EOS)
  519.             return(-32767);
  520.  
  521.         while(!isspace(*start) && *start!=EOS) start++;
  522.         if (*start==EOS)        /* Keine Kommandozeile */
  523.             drive=1;
  524.         *start=EOS;
  525.     
  526.         strcpy(source,fname);
  527.         if (drive==0)
  528.             {    start++;
  529.                 strcpy(temp,start);
  530.             }
  531.         else
  532.             { *temp=EOS;
  533.             }
  534.         trimstr(temp);                        /* Kommandozeile */
  535.         cmd[0]=strlen(temp);
  536.       cmd[1]=EOS;
  537.         strcpy(&cmd[1],temp);
  538.  
  539.         if (*(source+1)==':')
  540.             {    drive=toupper(*(source))-'A';
  541.                 Dsetdrv(drive);
  542.             }
  543.         getpfad(source,temp);
  544.         Dsetpath(temp);
  545.         sprintf(temp,"Executing %s %s",source,cmd+1);
  546.         log_it(temp);
  547.         return((int)Pexec(0,source,cmd,NULL));
  548.     }
  549.  
  550. void writenotify(void)
  551.     {    long seektemp;
  552.         int i;
  553.         MSG_HEADER nf;
  554.         char temp[MAX_STR],temp2[MAX_STR];
  555.  
  556.         seektemp = ftell(fhdr);
  557.         
  558.         strcpy(nf.szFrom,X_FIXNAME);
  559.         strcpy(nf.szTo,mh.szFrom);
  560.         strcpy(nf.szSubject,"Notify");
  561.         time(&nf.lDate);
  562.         strftime(nf.szDate,20,"%d %b %y %X",localtime(&nf.lDate) );
  563.  
  564.         nf.wFlags = MF_PRIVATE|MF_LOCAL;
  565. #if defined(TEST)
  566.         nf.wFlags |= MF_SENT;
  567. #endif
  568.  
  569.         delete_unused_flags(&nf);
  570.         nf.wFromZone =myzone;
  571.         nf.wFromNet  =mynet;
  572.         nf.wFromNode =mynode;
  573.         nf.wFromPoint=mypoint;
  574.         nf.wToZone   =mh.wFromZone;
  575.         nf.wToNet    =mh.wFromNet;
  576.         nf.wToNode   =mh.wFromNode;
  577.         nf.wToPoint  =mh.wFromPoint;
  578.  
  579.         sprintf(temp,"%s.MSG",netmail);
  580.         fmsg = fopen(temp,"a+b");
  581.  
  582.         nf.wSize = 0;
  583.         nf.lStart = ftell(fmsg);
  584.         mergeaddr(temp,myzone,mynet,mynode,mypoint,"");
  585.  
  586.         sprintf(temp2,"\001MSGID: %s %04x%04x\n",temp,(int) Random(), (int) Random());
  587.         fprintf(fmsg,temp2);
  588.         nf.wSize += (int) strlen(temp2);
  589.  
  590.         sprintf(temp2,X_PID);
  591.         fprintf(fmsg,temp2);
  592.         nf.wSize += (int) strlen(temp2);
  593.  
  594.         sprintf(temp2,"I have received and processed your mail!\n\n");
  595.         fprintf(fmsg,temp2);
  596.         nf.wSize += (int) strlen(temp2);
  597.  
  598.         for (i=1; i<=err_cnt; i++)
  599.             {    fputs(errstack[i].line,fmsg); putc('\n',fmsg);
  600.                 nf.wSize += (int) strlen(errstack[i].line) +1;
  601.             }
  602.  
  603.         sprintf(temp2,X_TEARLINE);
  604.         fprintf(fmsg,temp2);
  605.         nf.wSize += (int) strlen(temp2);
  606.  
  607.         fclose(fmsg);
  608.         
  609.         fseek(fhdr,0,SEEK_END);
  610.         fwrite(&nf,sizeof(MSG_HEADER),1,fhdr);
  611.         fseek(fhdr,seektemp,SEEK_SET);
  612.         log_it("Write notify");
  613.     }
  614.  
  615. void delete_unused_flags(MSG_HEADER *header)
  616.     {    int i;
  617.         header->wUp =
  618.         header->wReply =
  619.         header->wReadcount =
  620.         header->wCost = 0;
  621.         for (i=0; i<=3; i++)
  622.         *(long *)(&header->lMsgidcrc+i) = 0;
  623.     }
  624.  
  625. void convert(char *buffer, int *length)
  626.     {    int k,j;
  627.         char *src,*dst;
  628.         for (k=0; k<=(*length)-1; k++)
  629.             {    if (buffer[k]==1)
  630.                     {    for (j=k+1; j<=(*length)-1; j++)
  631.                             {    if (buffer[j]==10 || buffer[j]==0)
  632.                                     {    src=&buffer[k];
  633.                                         dst=&buffer[j]+1;
  634.                                         while (dst<=(&buffer[0]+ *length)) *src++=*dst++;
  635.                                         *length -= (int) (&buffer[j]-&buffer[k]+1);
  636.                                         k=-1;
  637.                                         break;
  638.                                     }
  639.                             }
  640.                     }
  641.             }
  642.     }
  643.  
  644. void getpfad(char *fname, char *xpfad)
  645.     {    register char *pointer;
  646.         pointer = strrchr(fname,'\\');
  647.         if (pointer==NULL)
  648.             *xpfad=EOS;
  649.         else
  650.             {    *pointer=EOS;
  651.                 strcpy(xpfad,fname);
  652.                 strcat(xpfad,"\\");
  653.                 *pointer='\\';
  654.             }
  655.     }
  656.  
  657. char *trimstr(char *str)
  658.     {    register char *pointer;
  659.         char *old=str;
  660.         while (isspace(*str) && (*str!=EOS)) str++;
  661.         pointer = strchr(str,EOS);
  662.         while (isspace(*(--pointer))!=0 && pointer>str) *pointer = EOS;
  663.         return(strcpy(old,str));
  664.     }
  665.  
  666. void trim(char **dest)
  667.     {    register char *pointer;
  668.         while (isspace(**dest)!=0 && *((*dest)++)!=EOS);
  669.         pointer = strchr(*dest,EOS);
  670.         while (isspace(*(--pointer))!=0 && pointer>*dest) *pointer = EOS;
  671.     }
  672.  
  673. void scanaddr(char *addr,int *zone,int *net,int *node,int *point,char *domain)
  674.     {    char *p,*q=NULL,*q1,*q2;
  675.         int chr;
  676.         
  677.         q1 = strchr(addr,'\n');
  678.         q2 = strchr(addr,'\r');
  679.         if (q1!=NULL && q2!=NULL)
  680.             q=MIN(q1,q2);
  681.         else if (q1!=NULL)
  682.             q=q1;
  683.         else if (q2!=NULL)
  684.             q=q2;
  685.         if (q!=NULL)
  686.             {    chr=*q;
  687.                 *q=EOS;
  688.             }
  689.  
  690.         p = strchr(addr, ':');
  691.     if (p)    *zone = atoi(addr);
  692.     else       *zone = 0;
  693.     p = strchr(addr, '/');
  694.     if (p)    {    p--;
  695.                     while (strchr("0123456789", *p) && (p >= addr)) p--;
  696.                     p++;
  697.                     *net = atoi(p);
  698.                     }
  699.     else    *net = 0;
  700.     p = strchr(addr, '/');
  701.     if (p)     { p++;
  702.                 *node = atoi(p);
  703.                     }
  704.     else    *node = atoi(addr);
  705.     p = strchr(addr, '.');
  706.     if (p)     { p++;
  707.                     *point = atoi(p);
  708.                     }
  709.     else    *point = 0;
  710.     p = strchr(addr, '@');
  711.     if (p)    { p++;
  712.                     sscanf(p,"%s",domain);
  713.                     }
  714.     else    *domain = EOS;
  715.     
  716.     if (q!=NULL)
  717.         *q=chr;
  718.     }
  719.  
  720. char *mergeaddr(char *addr,int zone,int net,int node,int point,char *domain)
  721.     { static char tmp[64];
  722.     *addr = EOS;
  723.     if (zone)    {    itoa(zone, tmp, 10);
  724.                             strcat(addr, tmp);
  725.                                 strcat(addr, ":");
  726.                           }
  727.     if (zone || net)    {    itoa(net, tmp, 10);
  728.                                                 strcat(addr, tmp);
  729.                                                 strcat(addr, "/");
  730.                                             }
  731.     itoa(node, tmp, 10);
  732.     strcat(addr, tmp);
  733.     if (point && node)    { strcat(addr, ".");
  734.                                               itoa(point, tmp, 10);
  735.                                                     strcat(addr, tmp);
  736.                                               }
  737.     if (*domain)    { strcat(addr, "@");
  738.                                 strcat(addr, domain);
  739.                                 }
  740.     return(addr);
  741. }
  742.  
  743. void input(char *string, int max, FILE *ftype)
  744.     {    char temp[512];
  745.         long len;
  746.         if (fgets(temp, max, ftype)!=NULL)
  747.             {    len = (int) strlen(temp);
  748.                 if (len>0)
  749.                     if (temp[len-1]=='\n')
  750.                         temp[len-1] = EOS;
  751.                 strcpy(string,temp);
  752.             }
  753.         else
  754.             {    *string = EOS;
  755.             }
  756.     }
  757.  
  758. void log_it(char *text)
  759.     {    char    temp[MAX_STR];
  760.         FILE    *fp;
  761.         time_t tim;
  762.  
  763.         if (*logfile!=EOS)
  764.             {    if ((fp=fopen(logfile,"a"))!=NULL)
  765.                     {    tim=time(NULL);
  766.                         strftime(temp,16,"%d %b %X",localtime(&tim));
  767.             fprintf(fp,"* %s DOOR %s\n",temp,text);
  768.                         fclose(fp);
  769.                     }
  770.             }
  771.     }
  772.  
  773. int    xFsfirst(const char *filename,int attr)
  774.     {    Fsetdta(&dta_buffer);
  775.         return (Fsfirst(filename,attr));
  776.     }
  777.  
  778. int    xFsnext(void)
  779.     {    return (Fsnext());
  780.     }
  781.  
  782. char *addr2file36(unsigned int net,unsigned int node,unsigned int point)
  783.     {    static char filename[13];
  784.         char dum[10],*pointer;
  785.  
  786.         itoa(net    ,dum,36);    sprintf(filename    ,"%3s",dum);
  787.         itoa(node ,dum,36);    sprintf(filename+3,"%3s",dum);
  788.         itoa(point,dum,36);    sprintf(filename+6,"%2s",dum);
  789.         pointer=filename;
  790.         while (*pointer!=EOS)
  791.             {    if (*pointer==' ')
  792.                     *pointer = '0';
  793.                 pointer++;
  794.             }
  795.         return(filename);
  796.     }
  797.  
  798. void add_slash(char *path)
  799.     {    if ( *path!=EOS )
  800.             if ( *(path+strlen(path)-1)!='\\' )
  801.                 strcat(path,"\\");
  802.     }
  803.  
  804.